<template>
  <div class="s-picker" :class="customClass">
    <s-popup
      :background="background"
      :z-index="zIndex"
      :value="visible"
      :position="position"
      :effect="effect"
      :effect-duration="effectDuration"
      :mask="mask"
      :mask-opacity="maskOpacity"
      :mask-close="maskClose"
      :before-show="beforeShow"
      @hide="hideAfter"
    >
      <div class="s-picker-header">
        <div class="cancel-btn" :style="{ color: $sTheme(cancelColor) }" @click="onCancel">{{ cancelText }}</div>
        <div class="title" :style="{ color: $sTheme(titleColor) }">{{ title }}</div>
        <div
          class="confirm-btn"
          :style="{ color: $sTheme(disabledConfirm ? cancelColor : confirmColor) }"
          @click="onConfirm"
        >
          {{ confirmText }}
        </div>
      </div>
      <div class="s-picker-body">
        <picker-view
          v-if="showContent"
          :value="selectedIndexList"
          class="picker-view"
          @change="slideChage"
          @pickstart="onPickStart"
          @pickend="onPickEnd"
        >
          <picker-view-column v-for="(listItem, listIndex) of list" :key="listIndex">
            <div v-for="(item, index) of listItem" :key="index" class="s-picker-item">{{ getLabelName(item) }}</div>
          </picker-view-column>
        </picker-view>
      </div>
    </s-popup>
  </div>
</template>

<script>
import SPopup from '../s-popup/s-popup';

/**
 * s-picker 底部弹出滑动选择组件 picker
 * @description 滑动选则，支持多列
 * @property {String|Object|Array} customClass 自定义class
 * @property {String} background 背景色
 * @property {String} position 显示位置 center | left | right | top | bottom | ''
 * @property {String|Number} zIndex z-index,如没指定，则在显示时使用比较自增
 * @property {Boolean} visible 双向绑定picker显示隐藏
 * @property {Boolean} effect 显示隐藏是否使用过渡效果
 * @property {Number} effectDuration 显示隐藏过渡效果时间 ms
 * @property {Boolean} visible 双向绑定picker显示隐藏 visible.sync
 * @property {Boolean} mask 是否显示遮罩
 * @property {Number} maskOpacity 遮罩透明度 0.7
 * @property {Boolean} maskClose 点击遮罩是否关闭
 * @property {Array} list 选择数据列表 [[{label:'中国'},{label:'美国'}]]
 * @property {String} labelName 取数据中的那个属性作为显示文字
 * @property {Array} value v-model双向绑定选中的下标数组 [0]
 * @property {String} title picker 标题
 * @property {String} titleColor picker 标题颜色
 * @property {String} cancelText 取消按钮文字
 * @property {String} cancelColor 取消按钮颜色
 * @property {String} confirmText 确认按钮文字
 * @property {String} confirmColor 确认按钮颜色
 * @event {Function} change (index, selectedIndexList) 滑动改变时触发
 * @event {Function} confirm (selectedIndexList) 点击确认时触发
 * @example <s-picker :list="list" :value="selectedIndexList" />
 */
export default {
  name: 'SPicker',
  components: {
    SPopup,
  },
  props: {
    customClass: {
      type: [String, Object, Array],
      default: '',
    },
    background: {
      type: String,
      default: '#ffffff',
    },
    position: {
      type: String,
      default: 'bottom',
    },
    zIndex: {
      type: [String, Number],
      default: 0,
    },
    visible: {
      type: Boolean,
      default: false,
    },
    effect: {
      type: Boolean,
      default: true,
    },
    effectDuration: {
      type: Number,
      default: 300,
    },
    mask: {
      type: Boolean,
      default: true,
    },
    maskOpacity: {
      type: Number,
      default: 0.7,
    },
    maskClose: {
      type: Boolean,
      default: true,
    },
    list: {
      type: Array,
      default: () => [],
    },
    labelName: {
      type: String,
      default: 'label',
    },
    value: {
      type: Array,
      default: () => [],
    },
    title: {
      type: String,
      default: '',
    },
    titleColor: {
      type: String,
      default: '{textPrimary}',
    },
    cancelText: {
      type: String,
      default: '取消',
    },
    cancelColor: {
      type: String,
      default: '{textSecondary}',
    },
    confirmText: {
      type: String,
      default: '确定',
    },
    confirmColor: {
      type: String,
      default: '{primary}',
    },
  },
  data() {
    return {
      selectedIndexList: [],
      showContent: false,
      disabledConfirm: false,
    };
  },
  watch: {
    value() {
      this.setIndex(this.value);
    },
  },
  methods: {
    beforeShow() {
      setTimeout(() => {
        this.setIndex(this.value);
        this.showContent = true;
      }, 50);
      return true;
    },
    hideAfter() {
      this.hide();
      this.showContent = false;
    },
    hide() {
      this.$emit('update:visible', false);
    },
    getLabelName(item) {
      return typeof item === 'object' && item ? item[this.labelName] : item;
    },
    onPickStart() {
      this.disabledConfirm = true;
    },
    onPickEnd() {
      this.disabledConfirm = false;
    },
    slideChage(e) {
      this.setIndex(e.detail.value);
    },
    setIndex(indexList) {
      const prevSelectedIndexList = this.selectedIndexList.slice(0);
      this.selectedIndexList = indexList;
      this.selectedIndexList.some((selectedIndex, i) => {
        if (selectedIndex != prevSelectedIndexList[i]) {
          this.$emit('change', i, this.selectedIndexList);
          return true;
        }
      });
    },
    onCancel() {
      this.hide();
      this.$emit('cancel');
    },
    onConfirm() {
      if (!this.disabledConfirm) {
        this.$emit('input', this.selectedIndexList);
        this.$emit('confirm', this.selectedIndexList);
        this.hide();
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.s-picker {
  &-header {
    height: 50px;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;

    .cancel-btn,
    .confirm-btn {
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100%;
      font-size: 14px;
      padding: 0 15px;
    }

    .title {
      flex: 1;
      font-size: 18px;
      text-align: center;
    }
  }

  &-body {
    height: 250px;

    .picker-view {
      height: 100%;
    }
  }

  &-item {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    padding: 0 3px;
  }
}
</style>
